import { _decorator, Component, Node, Label, UIOpacity, Animation } from 'cc';
import { Fight, MonsterEnum } from '../Entity/def/Fight';
import { MonsterEntity } from '../Entity/MonsterEntity';
import { Hero } from '../Hero/Hero';
import { FightFrame } from './FightFrame';
const { ccclass, property } = _decorator;

@ccclass('FightManage')
export class FightManage extends Component {

    private _frameTime = 500;

    private frames: FightFrame[] = []

    @property(Node)
    ml: Node = null

    @property(Label)
    mt: Label = null

    @property(Label)
    md: Label = null

    @property(Node)
    hl: Node = null

    @property(Label)
    ht: Label = null

    @property(Label)
    hd: Label = null


    start() {

    }

    update(deltaTime: number) {

    }

    fight(monster: MonsterEntity, hero: Hero, call: Function) {

        // 构建战斗帧，并检查是否可以胜利
        let success = this.buildFrame(monster, hero);
        if (!success) {
            this.frames.splice(0, this.frames.length);
            call(false)
            return
        }

        // 初始帧
        const initFrame = {
            mBlood: monster.fight.life,
            mDef: monster.fight.defense,
            mAtk: monster.fight.atk + monster.fight.magicAtk,
            hBlood: hero._heroState.fight.life,
            hDef: hero._heroState.fight.defense + hero._heroState.fight.magicDefense,
            hAtk: hero._heroState.fight.atk,
        }

        // 初始化面板
        this.setLabel(initFrame)
        this.node.active = true
        this.node.getComponent(UIOpacity).opacity = 255

        // 战斗动画延迟600ms
        setTimeout(() => {
            // 播放战斗动画
            this.playFrame(0)
            setTimeout(() => {
                call(true, this.frames[this.frames.length - 1])
                this.frames.splice(0, this.frames.length);
                this.node.active = false
            }, this._frameTime * (this.frames.length + 1))
        }, 600)
    }

    private buildFrame(monster: MonsterEntity, hero: Hero): boolean {
        return this.doFight({
            type: monster.fight.type,
            life: monster.fight.life,
            defense: monster.fight.defense,
            magicAtk: monster.fight.magicAtk,
            atk: monster.fight.atk
        }, {
            life: hero._heroState.fight.life,
            magicDefense: hero._heroState.fight.magicDefense,
            defense: hero._heroState.fight.defense,
            atk: hero._heroState.fight.atk
        })
    }

    private doFight(monster: Fight, hero: Fight): boolean {

        // 怪物进攻
        let physical = monster.atk - hero.defense
        physical = physical >= 0 ? physical : 0
        let magic = monster.magicAtk - hero.magicDefense
        magic = magic >= 0 ? magic : 0
        hero.life -= (magic + physical)

        // 英雄血量为0则返回 无法战胜
        if (hero.life <= 0) {
            return false;
        }

        // 英雄进攻
        const mDeleteBlood = hero.atk - monster.defense
        monster.life -= mDeleteBlood

        // 添加帧
        this.frames.push({
            mBlood: monster.life <= 0 ? 0 : monster.life,
            mDef: monster.defense,
            mAtk: monster.atk + monster.magicAtk,
            hBlood: hero.life,
            hDef: hero.defense + hero.magicDefense,
            hAtk: hero.atk,
        })

        // 怪物血量为0，进攻胜利
        if (monster.life <= 0) {
            return true;
        }

        // 下一轮攻击
        return this.doFight(monster, hero)
    }

    private playFrame(index: number) {
        if (index >= this.frames.length) {
            return
        }
        this.doPlay(this.frames[index++])
        setTimeout(() => {
            this.playFrame(index)
        }, this._frameTime)
    }

    private doPlay(fight: FightFrame) {
        this.setLabel(fight)
    }

    private setLabel(fight: FightFrame) {
        this.ml.getComponent(Label).string = fight.mBlood + ''
        this.mt.string = fight.mAtk + ''
        this.md.string = fight.mDef + ''
        this.hl.getComponent(Label).string = fight.hBlood + ''
        this.ht.string = fight.hAtk + ''
        this.hd.string = fight.hDef + ''
        this.playAnim()
    }

    private playAnim() {
        this.ml.getComponent(Animation).play('atk')
        this.hl.getComponent(Animation).play('atk')
    }
}

